package com.shali.cloud.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.shali.cloud.entity.User;

@RestController
public class MovieController {

	@Autowired
	private RestTemplate restTemplate;

	@GetMapping("/movie/{id}")
	/**
	 * If you want some thread local context to propagate into a @HystrixCommand the default declaration will not work because it executes the command in a thread pool (in case of timeouts). 
	 * You can switch Hystrix to use the same thread as the caller using some configuration, 
	 * or directly in the annotation, by asking it to use a different "Isolation Strategy". 
	 * For example:
	 */
	@HystrixCommand(fallbackMethod = "findByIdDefault",
		commandProperties = {
					@HystrixProperty(name="execution.isolation.strategy",value="SEMAPHORE")
				}
	)
	/**
	 * The same thing applies if you are using @SessionScope or @RequestScope. 
	 * You will know when you need to do this because of a runtime exception that says it can’t find the scoped context.
	 * You also have the option to set the hystrix.
	 * shareSecurityContext property to true. 
	 * Doing so will auto configure an Hystrix concurrency strategy plugin hook who will transfer the SecurityContext from your main thread to the one used by the Hystrix command. 
	 * Hystrix does not allow multiple hystrix concurrency strategy to be registered so an extension mechanism is available by declaring your own HystrixConcurrencyStrategy as a Spring bean. 
	 * Spring Cloud will lookup for your implementation within the Spring context and wrap it inside its own plugin.
	 * @param id
	 * @return
	 */
	public User findById(@PathVariable Long id) {
		
		//VIP(virtual IP) microservice-provider-user
		return this.restTemplate.getForObject("http://microservice-provider-user/findOne/"+id, User.class);
	}

	public User findByIdDefault(Long id) {
		User user = new User();
		user.setId(1L);
		return user;
	}
}
